class Compiler {
	constructor(vm) {
		this.vm = vm
		this.el = vm.$el
		this.compile(this.el)
	}
	compile(el) {
		let nodesList = el.childNodes;
		Array.from(nodesList).forEach((node) => {
			if (this.isTextNode(node)) { //文本节点
				this.compileText(node)
			} else if (this.isElementNode(node)) {
				this.compileElement(node)
			}

			if (node.childNodes && node.childNodes.length) {
				this.compile(node)
			}
		})
	}

	compileText(node) {
		//判断节点是普通文本还是插值表达式
		let reg = /\{\{(.+?)\}\}/;
		let nodeVal = node.textContent;
		if (reg.test(nodeVal)) {
			let key = RegExp.$1.trim() //取得msg
			node.textContent = nodeVal.replace(reg, this.vm[key])

			//创建wather ,更新视图
			new Watcher(this.vm, key, (newVal) => {
				node.textContent = newVal
			})
		}
	}

	compileElement(node) {
		let attributes = node.attributes;

		Array.from(attributes).forEach((attr) => {
			let attrName = attr.name;
			//判断属性是否指令
			if (this.isDirective(attrName)) {
				attrName = attrName.substr(2); //获取v-text中的text
				let attrValue = attr.value; //即'msg'
				this.update(node, this.vm[attrValue], attrName)

			}
		})
	}
	isTextNode(node) {
		return node.nodeType === 3
	}

	isElementNode(node) {
		return node.nodeType === 1
	}
	isDirective(attrName) {
		return attrName.startsWith('v-')
	}
	update(node, key, attrName) {
		let updateFun = this[attrName + 'Updater']
		updateFun && updateFun.call(this, node, this.vm[key], key)
	}

	textUpdater(node, value, key) {
		node.textContent = value
		new Watcher(this.vm, key, (newValue) => {
			node.textContent = newValue
		})
	}
}